package crm8000.services

import crm8000.Models.CustomerCategory;
import crm8000.Models.Receivables;
import crm8000.Models.ReceivablesDetail;
import crm8000.Models.SupplierCategory;
import crm8000.Models.User;
import crm8000.Models.WSBill;
import crm8000.Models.WsReceiving;
import crm8000.helper.Result
import crm8000.viewModels.ReceivablesDetailVM
import crm8000.viewModels.ReceivablesVM;
import grails.transaction.Transactional

@Transactional
class RvService {
	UserService userService

	def categoryList(String id) {
		if (id == "customer") {
			return CustomerCategory.listOrderByCode()
		} else {
			return SupplierCategory.listOrderByCode()
		}
	}

	def rvListTotalCount(params) {
		def caType = params.caType
		def categoryId = params.categoryId

		String hql
		if (caType == "customer") {
			hql = ''' select count(*)
						from crm8000.Models.Receivables as r , crm8000.Models.Customer as c
						where r.caId = c.id and c.category.id = :categoryId
					'''
		} else {
			hql = ''' select count(*)
						from crm8000.Models.Receivables as r , crm8000.Models.Supplier as c
						where r.caId = c.id and c.category.id = :categoryId
					'''
		}

		def data = Receivables.executeQuery(hql, [categoryId: categoryId])

		return data[0]
	}

	def rvList(params) {
		def caType = params.caType
		def categoryId = params.categoryId

		String hql
		if (caType == "customer") {
			hql = ''' select r.id as id, c.code as code, c.name as name, r.rvMoney as rvMoney, 
							r.actMoney as actMoney, r.balanceMoney as balanceMoney, c.id as caId
						from crm8000.Models.Receivables as r , crm8000.Models.Customer as c
						where r.caId = c.id and c.category.id = :categoryId
						order by c.code asc
					'''
		} else {
			hql = ''' select r.id as id, c.code as code, c.name as name, r.rvMoney as rvMoney, 
							r.actMoney as actMoney, r.balanceMoney as balanceMoney, c.id as caId
						from crm8000.Models.Receivables as r , crm8000.Models.Supplier as c
						where r.caId = c.id and c.category.id = :categoryId
						order by c.code asc
					'''
		}

		def result = []

		Receivables.executeQuery(hql, [categoryId: categoryId], [max: params.limit, offset: params.start]).each {
			result.add(new ReceivablesVM(id: it[0], code: it[1],
			name: it[2], rvMoney: it[3], actMoney: it[4],
			balanceMoney: it[5], caId: it[6]))
		}

		return result
	}

	def rvDetailListTotalCount(params) {
		def caType = params.caType
		def caId = params.caId

		return 	ReceivablesDetail.createCriteria().get {
			projections { count("id") }
			eq("caType", caType)
			eq("caId", caId)
		}
	}

	def rvDetailList(params) {
		def caType = params.caType
		def caId = params.caId

		def result = []

		def data = ReceivablesDetail.createCriteria().list {
			eq("caType", caType)
			eq("caId", caId)
			order "refNumber", "desc"
		}

		data.each {
			def vm = new ReceivablesDetailVM()
			vm.id = it.id
			vm.refType = it.refType
			vm.refNumber = it.refNumber
			vm.actMoney = it.actMoney
			vm.rvMoney = it.rvMoney
			vm.balanceMoney = it.balanceMoney

			if (it.refType == "销售出库") {
				def bill = WSBill.findByRef(it.refNumber)
				if (bill) {
					vm.bizDT = bill.bizDT.format("yyyy-MM-dd")
				}
			}
			result.add(vm)
		}

		return result
	}

	def rvRecordList(params) {
		def refType = params.refType
		def refNumber = params.refNumber

		if (refType == "销售出库"){
			return WsReceiving.createCriteria().list(max: params.limit, offset: params.start) {
				wsBill { eq ("ref", refNumber) }
				order "bizDate", "desc"
				order "dateCreated", "desc"
			}
		}
		else {
			return []
		}
	}

	def rvRecordListTotalCount(params) {
		def refType = params.refType
		def refNumber = params.refNumber

		if (refType == "销售出库"){
			return WsReceiving.createCriteria().get {
				projections { count("id")}
				wsBill { eq ("ref", refNumber) }
			}
		}
		else {
			return 0
		}
	}

	Result addRvRecord(params) {
		def refType = params.refType
		def refNumber = params.refNumber
		
		def actMoney = params.actMoney.toBigDecimal()
		
		def bizDate = Date.parse("yyyy-MM-dd", params.bizDT)

		if (refType == "销售出库") {
			def bill = WSBill.findByRef(refNumber)
			if (!bill) {
				return new Result(success:false, msg: "单号为${refNumber}的销售出库单不存在")
			}
			
			def bizUser = User.get(params.bizUserId)
			if (!bizUser) {
				return new Result(success: false, msg: "收款人不存在")
			}
			
			def rvDetail = ReceivablesDetail.createCriteria().get {
				eq "refType", refType
				eq "refNumber", refNumber
			}
			if (!rvDetail) {
				return new Result(success: false, msg: "应收账款明细账记录不存在，请联系系统管理员")
			}
			def rv = Receivables.createCriteria().get {
				eq "caId", rvDetail.caId
				eq "caType", rvDetail.caType
			}
			if (!rv) {
				return new Result(success: false, msg: "应收账款记录不存在，请联系系统管理员")
			}
			
			def rec = new WsReceiving()
			rec.actMoney = actMoney
			rec.bizDate = bizDate
			rec.inputUser = userService.loginUser
			rec.remark = params.remark
			rec.rvUser = bizUser
			rec.wsBill = bill
			
			rec.save()
			
			// 修改应收账款已收和余额
			rv.actMoney += rec.actMoney
			rv.balanceMoney = rv.rvMoney - rv.actMoney
			rv.save()
			
			rvDetail.actMoney += rec.actMoney
			rvDetail.balanceMoney = rvDetail.rvMoney - rvDetail.actMoney
			rvDetail.save()
			
			return new Result(success: true, id: rec.id)
		}

		return new Result(success: false, msg: "TODO")
	}
	
	def refreshRvInfo(String id) {
		return Receivables.get(id)
	}
	
	def refreshRvDetailInfo(String id) {
		return ReceivablesDetail.get(id)
	}
}
